package com.springboot.frame.socketio;

import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.annotation.SpringAnnotationScanner;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * socketio 的spring-boot启动器
 *
 * @author liheng
 */
@Configuration
@EnableConfigurationProperties(SocketIoProperties.class)
@ConditionalOnProperty(name = "socketio.enabled")
public class SocketIoAutoConfiguration {

    private final SocketIoProperties properties;

    public SocketIoAutoConfiguration(SocketIoProperties properties) {
        this.properties = properties;
    }

    /**
     * SocketIOServer配置
     *
     * @param
     * @return com.corundumstudio.socketio.SocketIOServer
     */
    @Bean
    @ConditionalOnMissingBean
    public SocketIOServer socketIOServer() {
        com.corundumstudio.socketio.Configuration config = new com.corundumstudio.socketio.Configuration();
        // 配置端口
        config.setPort(this.properties.getPort());
        // 开启Socket端口复用
        com.corundumstudio.socketio.SocketConfig socketConfig = new com.corundumstudio.socketio.SocketConfig();
        socketConfig.setReuseAddress(true);
        config.setSocketConfig(socketConfig);
        // 连接数大小
        config.setWorkerThreads(this.properties.getWorkCount());
        // 允许客户请求
        config.setAllowCustomRequests(this.properties.isAllowCustomRequests());
        // 协议升级超时时间(毫秒)，默认10秒，HTTP握手升级为ws协议超时时间
        config.setUpgradeTimeout(this.properties.getUpgradeTimeout());
        // Ping消息超时时间(毫秒)，默认60秒，这个时间间隔内没有接收到心跳消息就会发送超时事件
        config.setPingTimeout(this.properties.getPingTimeout());
        // Ping消息间隔(毫秒)，默认25秒。客户端向服务器发送一条心跳消息间隔
        config.setPingInterval(this.properties.getPingInterval());
        // 设置HTTP交互最大内容长度
        config.setMaxHttpContentLength(this.properties.getMaxHttpContentLength());
        // 设置最大每帧处理数据的长度，防止他人利用大数据来攻击服务器
        config.setMaxFramePayloadLength(this.properties.getMaxFramePayloadLength());
        return new SocketIOServer(config);
    }

    /**
     * 开启SocketIOServer注解支持
     *
     * @param socketServer
     * @return com.corundumstudio.socketio.annotation.SpringAnnotationScanner
     */
    @Bean
    public SpringAnnotationScanner springAnnotationScanner(SocketIOServer socketServer) {
        return new SpringAnnotationScanner(socketServer);
    }

}
